/*
 *  Copyright 2015-2016, RenGu Technology (BeiJing) Co., Ltd.
 *  All right reserved.
 *
 *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF RENGU TECHNOLOGY (BeiJing) CO., LTD.
 *
 *  THE CONTENTS OF THIS FILE MAY NOT BE DISCLOSED TO THIR PARTIES,
 *  COPIED OR DUPLICATED IN ANY FORM, IN WHOLE OR IN PART,
 *  WITHOUT THE PRIOR WRITTEN PERMISSION OF RENGU TECHNOLOGY (BeiJing) CO., LTD.
 *
 *  IntelliQryChnlService.java
 *
 *  Edit History:
 *      lizhangtao Created on 2022年01月11日
 *
 */
package cc.rengu.igas.route.core.service.trans;

import cc.rengu.igas.route.common.constant.SmartRouteParamConstant;
import cc.rengu.igas.route.common.enums.SmartRouteRspEnums;
import cc.rengu.igas.route.facade.bean.ViewChannelInfo;
import cc.rengu.igas.route.facade.request.IntelliQryChnlRequest;
import cc.rengu.igas.route.facade.response.IntelliQryChnlResponse;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.ChannelCallCfgMapper;
import cc.rengu.oltp.service.common.dao.DstChannelInfoMapper;
import cc.rengu.oltp.service.common.dao.DstTxnAuthCfgMapper;
import cc.rengu.oltp.service.common.dao.impl.ChannelCallCfgMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.DstChannelInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.DstTxnAuthCfgMapperImpl;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.DstChannelInfo;
import cc.rengu.oltp.service.common.entity.DstTxnAuthCfg;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.base.StringUtil;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 查询可供路由的通道信息
 *
 * @author lizhangtao
 * @version 1.0
 * @date 2022/1/11
 */
public class IntelliQryChnlService extends RadpService {
    /**
     * Biz init int.
     *
     * @param s the s
     * @return the int
     */
    @Override
    protected int bizInit(String s) {
        return 0;
    }

    /**
     * Biz process int.
     *
     * @param s the s
     * @param i the
     * @return the int
     */
    @Override
    protected int bizProcess(String s, int i) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        try {
            IntelliQryChnlRequest request = new IntelliQryChnlRequest();
            ConvertUtil.convertOutput(request);
            //参数为空判断
            if (StringUtil.isNullorEmpty(request.getHeader().getInstId()) ||
                    StringUtil.isNullorEmpty(request.getHeader().getSrcSysId()) ||
                    StringUtil.isNullorEmpty(request.getHeader().getChanlId())) {
                rglog.error("必须输入机构号<{}>，发起系统<{}>、渠道号<{}>", request.getHeader().getInstId(),
                        request.getHeader().getSrcSysId(), request.getHeader().getChanlId());
                throw new BizException(SmartRouteRspEnums.MSG_VALID_CHECK_ERROR.getRespCode(), SmartRouteRspEnums.MSG_VALID_CHECK_ERROR.getRespDesc());
            }

            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.SRC_SYS_ID, request.getHeader().getSrcSysId());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM, request.getHeader().getTraceNo());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TRANS_TIME, request.getHeader().getTransTime());
            xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TRANS_DATE, request.getHeader().getTransDate());

            IntelliQryChnlResponse response = new IntelliQryChnlResponse();
            response.setHeader(request.getHeader());
            List<ViewChannelInfo> viewChannelInfoList = new ArrayList<>();
            response.setViewChannelInfoList(viewChannelInfoList);
            //查询智能路由支持的通道
            //查询redis，不存在或者失败再降级查询数据库
            ChannelCallCfgMapper channelCallCfgMapper = new ChannelCallCfgMapperImpl();
            List<ChannelCallCfg> channelCallCfgs = channelCallCfgMapper.selectChannelCallCfgByTxnNum(request.getHeader().getInstId(), SmartRouteParamConstant.IGRT,
                    SmartRouteParamConstant.ALL, request.getQryTxnNum(), SmartRouteParamConstant.STRING_TWO_ZERO);
            Optional.ofNullable(channelCallCfgs).orElseThrow(() -> {
                rglog.error("获取交易码映射表失败");
                return new BizException(SmartRouteRspEnums.CONFIG_ERROR.getRespCode(), SmartRouteRspEnums.CONFIG_ERROR.getRespDesc());
            });
            for (ChannelCallCfg channelCallCfg : channelCallCfgs) {
                rglog.warn("该通道<{}：{}：{}>", channelCallCfg.getInstId(), channelCallCfg.getCallChannelId(), channelCallCfg.getCallChannelTxn());
                //获取通道信息
                DstChannelInfo dstChannelInfo = null;
                String dstChannelInfoKey = channelCallCfg.getInstId().trim() + channelCallCfg.getCallChannelId().trim();
                try {
                    dstChannelInfo = JSON.parseObject(RedisUtil.hashGet(AppParamConstant.CHANNEL_ISS_INFO_CACHE, dstChannelInfoKey), DstChannelInfo.class);
                } catch (Exception e) {
                    rglog.warn("redis中未查询到key<{}>通道信息", dstChannelInfoKey);
                }
                if (null == dstChannelInfo) {
                    DstChannelInfoMapper dstChannelInfoMapper = new DstChannelInfoMapperImpl();
                    dstChannelInfo = dstChannelInfoMapper.selectDstChannelInfoByPrimaryKey(channelCallCfg.getInstId().trim(), channelCallCfg.getCallChannelId().trim());
                }
                if (null == dstChannelInfo) {
                    //未配置该通道
                    rglog.warn("该通道<{}：{}>未配置通道信息", channelCallCfg.getInstId(), channelCallCfg.getCallChannelId());
                    continue;
                }
                //排除本行通道
                if (SmartRouteParamConstant.ESB.equalsIgnoreCase(dstChannelInfo.getDstChannelId()) ||
                        SmartRouteParamConstant.ESBMS.equalsIgnoreCase(dstChannelInfo.getDstChannelId())) {
                    rglog.warn("过滤本行通道");
                    continue;
                }
                //获取通道交易权限信息
                DstTxnAuthCfg dstTxnAuthCfg = null;
                String dstTxnAuthKey = SmartRouteParamConstant.ROUTE_CONF_DST_TXN_AUTH + ":" + channelCallCfg.getInstId() + ":" + channelCallCfg.getCallChannelId() + ":" + channelCallCfg.getCallChannelTxn();
                try {
                    dstTxnAuthCfg = JSON.parseObject(RedisUtil.onceGet(dstTxnAuthKey), DstTxnAuthCfg.class);
                } catch (Exception e) {
                    rglog.warn("redis中未查询到key<{}>通道交易权限信息", dstTxnAuthKey);
                }
                if (null == dstTxnAuthCfg) {
                    //查询数据库
                    DstTxnAuthCfgMapper dstTxnAuthCfgMapper = new DstTxnAuthCfgMapperImpl();
                    dstTxnAuthCfg = dstTxnAuthCfgMapper.selectDstTxnAuthCfgByPrimaryKey(channelCallCfg.getInstId(), channelCallCfg.getCallChannelId(), channelCallCfg.getCallChannelTxn());
                }
                if (null == dstTxnAuthCfg) {
                    rglog.warn("该通道<{}：{}：{}>没有配置支持智能路由的通道交易", channelCallCfg.getInstId(), channelCallCfg.getCallChannelId(), channelCallCfg.getCallChannelTxn());
                    continue;
                }
                ViewChannelInfo viewChannelInfo = new ViewChannelInfo();
                viewChannelInfo.setDstChannelId(dstChannelInfo.getDstChannelId());
                viewChannelInfo.setChannelDesc(channelCallCfg.getCallChannelTxnName());
                viewChannelInfo.setChannelFeeRate(dstTxnAuthCfg.getChannelTxnRate());
                viewChannelInfoList.add(viewChannelInfo);
            }

            if (viewChannelInfoList.isEmpty()) {
                rglog.error("无可用通道");
                throw new BizException(SmartRouteRspEnums.NO_AVAILABLE_DST_CHANNEL_ERROR.getRespCode(), SmartRouteRspEnums.NO_AVAILABLE_DST_CHANNEL_ERROR.getRespDesc());
            }

            response.setRespCode(SmartRouteRspEnums.TRANS_SUCCESS.getRespCode());
            response.setRespDesc(SmartRouteRspEnums.TRANS_SUCCESS.getRespDesc());
            ConvertUtil.convertInput(response);
        } catch (BizException e) {
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, e.getCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, e.getMessage());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e1));
            }
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, SmartRouteRspEnums.TRANS_FAIL.getRespCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, SmartRouteRspEnums.TRANS_FAIL.getRespDesc());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e1));
            }
        }
        return 0;
    }

    /**
     * Biz terminate int.
     *
     * @param s the s
     * @return the int
     */
    @Override
    protected int bizTerminate(String s) {
        return 0;
    }
}
